package ycl.scheduled.service.impl;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONObject;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ycl.scheduled.common.constants.RedisConstant;
import ycl.scheduled.common.models.req.login.WechatLoginReq;
import ycl.scheduled.common.models.res.login.LoginRes;
import ycl.scheduled.common.utils.BeanConvertUtil;
import ycl.scheduled.common.utils.CryptoUtil;
import ycl.scheduled.entity.SysUser;
import ycl.scheduled.mapper.SysUserMapper;
import ycl.scheduled.service.SecurityService;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

/**
 * @author: YCL
 * @date: 2022/01/20 10:41:09
 */
@Service("securityService")
public class SecurityServiceImpl implements SecurityService {

	@Resource
	private SysUserMapper userMapper;
	@Resource
	private StringRedisTemplate stringRedisTemplate;

	@Override
	@Transactional(rollbackFor = Exception.class)
	public SysUser register(String wechatId) {
		boolean exist = userMapper.existByWechatId(wechatId);
		Assert.isFalse(exist, "用户已存在, 请登录");
		SysUser user = new SysUser();
		//生成邀请码
		do {
			String code = RandomUtil.randomStringUpper(8);
			boolean b = userMapper.existByInvitationCode(code);
			if (! b) {
				user.setInvitationCode(code);
				break;
			}
		} while (true);

		user
				//生成加密盐
				.setSalt(RandomUtil.randomString(20))
				//微信id
				.setWechatId(wechatId)
				//注册时间
				.setRegisterTime(LocalDateTime.now());
		userMapper.insert(user);
		return user;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public LoginRes wechatLogin(WechatLoginReq req) {
		String wechatId = req.getWechatId();
		SysUser user = userMapper.selectByWechatId(wechatId);
		Assert.notNull(user,"未找到用户");
		System.out.println(JSONObject.toJSONString(user));
		return login(user, wechatId, req.getIp());
	}

	private LoginRes login(SysUser user, String wechatId, String ip) {
		Assert.isTrue(user.getStatus() == 0, "抱歉, 您被禁用, 不可登录");
		Assert.isFalse(user.getLocked(), "抱歉, 您的账户被上锁, 不可登录");
		LoginRes res = BeanConvertUtil.convert(user, LoginRes.class);
		String token = CryptoUtil.cryptoToken(wechatId);

		userMapper.login(user.getId(), token, ip);
		res.setToken(token);

		stringRedisTemplate.opsForValue().set(
				RedisConstant.USER_LOGIN + token,
				JSONObject.toJSONString(res),
				30L,
				TimeUnit.DAYS
		);
		return res;
	}
}
